/******************************************************************
 * Created by: Goh Chee Hong                                       
 * Date of Creation: 1/1/2009
 * Date of last modification: 31/1/2009
 * Status: Optimized and Finished
 *                                                                
 * Description: Receiving a file
 ******************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Pbdms.BusinessLogic;
using Pbdms.Common.Interfaces;

using Pbdms.NetworkDealer;
using Pbdms.Common.DataObject;
namespace Pbdms.BusinessLogic.FileTransfer
{
    public partial class FileTransferReceiverGui :FileTransferGui
    {

        /// <summary>
        /// saved file location
        /// </summary>
      

        /// <summary>
        /// file size
        /// </summary>
        private long filesize;
        /// <summary>
        /// thread that handle the download
        /// </summary>
        private Thread thTransfer=null;


      
        
      


        public FileTransferReceiverGui()
        {

        }
        /// <summary>
        ///  delcare method
        /// </summary>
        /// <param name="keyID"></param>
        /// <param name="friendName"></param>
        /// <param name="fileName"></param>
        /// <param name="size"></param>
        /// <param name="connection"></param>
        /// <param name="networkController"></param>
        public FileTransferReceiverGui(string keyID,string friendName,string fileName,long size,object connection,Network.NetworkController networkController):base(){
          
            this.keyID = keyID;
            this.fileName = fileName;
            this.networkController = networkController;
            this.friendName = friendName;
            this.lblUser.Text = friendName;
           
            this.filesize = size;
            this.authTcpClient = (AuthTcpClient)connection;
            this.lblStatus.Text = "Waiting for transfer";
            this.fileInfo = new System.IO.FileInfo(fileName);
            this.lblDoc.Text = fileInfo.Name;
        }
    
        /// <summary>
        /// start method
        /// </summary>
        public  override void start()
        {

            thTransfer = new Thread(new ThreadStart(receive));
            thTransfer.IsBackground = true;
            thTransfer.Start();
            
        }
        /// <summary>
        /// 
        /// </summary>
        private void receive()
        {
            System.IO.FileStream fout = null;
            
            try
            {
                ///send the message granted
                NetworkMessage message = new NetworkMessage();
                message.TypeOfMessage = NetworkDealer.NetworkDealer.TRANSFER_FILE_REQUEST_GRANTED;
                authTcpClient.sendMessage(message);
                displayStatus("Accepted the file transfer");

                //starts receiving
                long rby = 0;
                int perc = 0;

                fout = new FileStream(fileName, FileMode.Create, FileAccess.Write);
                
                string currentDownload = Common.Global.GetFileSize(rby);
                string totalString = Common.Global.GetFileSize(filesize);
                displayStatus("downloading " + currentDownload + " of " + totalString);
                int before = 0;
                while (rby < filesize)
                {
                    byte[] buffer = null;
                    //Read from the Network Stream
                    try
                    {
                        ///measure the length of the block
                        int length = 1024;
                        if (rby + 1024 > filesize)
                        {
                            length = (int)(filesize - rby);
                        }

                        //receive the bytes
                        buffer = authTcpClient.receiveBytes();
                        fout.Write(buffer, 0, buffer.Length);
                        rby = rby + buffer.Length;
                        perc = (int)(((double)rby / (double)filesize) * 100.00);
                        if (before != perc)
                        {
                            displayProgress(perc.ToString());
                            currentDownload = Common.Global.GetFileSize(rby);
                            totalString = Common.Global.GetFileSize(filesize);
                            Thread.Sleep(100);
                        }
                        displayStatus("downloading " + currentDownload + " of " + totalString);
                        Thread.Sleep(100);
                        before = perc;
                    }
                    catch
                    {
                        break;
                    }
                }

                //complete transferred
                if (rby == filesize)
                {
                    //no error
                    finished = true;
                    displayStatus("Finished downloading");
                }
                else
                {
                    displayStatus("The connection is disconnected");
                    fout.Close();
                    File.Delete(fileName);
                }
                //signal it is finished
                Finished("");
                fout.Close();
            }
            catch
            {
                try
                {
                    displayStatus("The connection is disconnected");
                    Finished("");
                }
                catch
                {
                  
                }
            }
            finally
            {
                //close connection
                if (fout != null)
                {
                    fout.Close();
                }
                finished = true;
                authTcpClient.Close();
            }
        }

    }
}
